package com.example.login.username;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import com.example.security.InfoDetail;
import com.example.security.UserDetail;
import com.example.utils.ConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.OAuth2Token;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * 帐号密码登录认证
 */


public class UsernameAuthenticationProvider implements AuthenticationProvider {
    private UserDetailsService userDetailsService;
    private PasswordEncoder passwordEncoder;

    private JdbcTemplate jdbcTemplate;

    public UsernameAuthenticationProvider(@Qualifier("UserDetailsServiceImpl") UserDetailsService userDetailsService,
                                          PasswordEncoder passwordEncoder,
                                          JdbcTemplate jdbcTemplate){
        this.passwordEncoder = passwordEncoder;
        this.jdbcTemplate = jdbcTemplate;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 用户提交的用户名 + 密码：
        String username = (String) authentication.getPrincipal();
        String password = (String) authentication.getCredentials();

        // 查数据库，匹配用户信息
        UserDetail userDetail = (UserDetail) userDetailsService.loadUserByUsername(username);
        if (!passwordEncoder.matches(password, userDetail.getPassword())) {
            throw new BadCredentialsException("用户名密码错误");
        }

//        JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
//        Long clientPrimaryId = userDetail.getClientPrimaryId();
//        RegisteredClient client = registeredClientRepository.findById(String.valueOf(clientPrimaryId));
//        if (client == null) {
//            throw new BadCredentialsException("客户端不存在");
//        }


        UsernameAuthentication token = new UsernameAuthentication();
        InfoDetail infoDetail = ConvertUtils.sourceToTarget(userDetail, InfoDetail.class);
//        infoDetail.setClientPrimaryId(clientPrimaryId);
//        infoDetail.setClientId(client.getClientId());
//        String clientSecretNoop = userDetail.getClientSecretNoop();
//        infoDetail.setClientSecret(clientSecretNoop);
//        Set<String> postLogoutRedirectUris = client.getPostLogoutRedirectUris();
//        String url = ListUtil.toList(postLogoutRedirectUris).get(0);
//        infoDetail.setPostLogoutRedirectUris(url);
//        Set<String> scopes = client.getScopes();
//        if (CollectionUtil.isEmpty(scopes)) {
//            throw new BadCredentialsException("client的scope不能为空");
//        }
//        String join = String.join(" ", scopes);
//        infoDetail.setScopes(join);
        token.setInfoDetail(infoDetail);
        token.setAuthenticated(true); // 认证通过，这里一定要设成true
        token.setUsername(username);
        token.setPassword(password);
        return token;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(UsernameAuthentication.class);
    }
}

